package com.qipa.utils;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.Charset;
import java.util.*;

public class HttpKit {
    private static PoolingHttpClientConnectionManager cm;
    private static String EMPTY_STR = "";
    private static RequestConfig requestConfig;
    private static final int SOCKET_TIMEOUT = 1 * 20 * 1000; // 默认超时时间， 单位毫秒
    private static final int REQUEST_TIMEOUT = 10 * 1000; // 默认超时时间， 单位毫秒
    private static final int DEFAULT_CONNECTION_TIMEOUT = 10 * 60 * 1000; // 10分钟 默认超时时间， 单位毫秒
    private static final int MAX_TOTAL = 200;
    private static final int MAX_PER_ROUTE = 50;
    public static final Charset UTF_8 = Charset.forName("UTF-8");

    private static Logger logger = LoggerFactory.getLogger(HttpKit.class);

    private static void init() {
        if (cm == null) {
            cm = new PoolingHttpClientConnectionManager();
            cm.setMaxTotal(MAX_TOTAL);// 整个连接池最大连接数
            cm.setDefaultMaxPerRoute(MAX_PER_ROUTE);// 每路由最大连接数，默认值是2
        }

        if (requestConfig == null) {
            requestConfig = RequestConfig.custom()
                    .setConnectionRequestTimeout(DEFAULT_CONNECTION_TIMEOUT) // 连接池获取timeout
                    .setConnectTimeout(REQUEST_TIMEOUT) // 请求timeout
                    .setSocketTimeout(SOCKET_TIMEOUT) // 读取数据timeout
                    .build();
        }

    }

    /**
     * 通过连接池获取HttpClient
     */
    private static CloseableHttpClient getHttpClient() {
        init();
        return HttpClients.custom()
                .setConnectionManager(cm)
                .setDefaultRequestConfig(requestConfig)
                .build();
    }

    public static String get(String url) {
        try {
            HttpGet httpGet = new HttpGet(url);
            return getResult(httpGet);
        } catch (Exception e) {
            logger.error("请求异常，请求URL={}", url, e);
        }
        return EMPTY_STR;
    }

    public static String get(String url, Map<String, Object> params) throws Exception {
        URIBuilder ub = new URIBuilder();
        ub.setPath(url);

        if(params != null){
            ArrayList<NameValuePair> pairs = covertParams2NVPS(params);
            ub.setParameters(pairs);
        }

        HttpGet httpGet = new HttpGet(ub.build());
        return getResult(httpGet);
    }

    public static String get(String url, Map<String, Object> headers, Map<String, Object> params) throws Exception {
        logger.info("GET请求url："+url);
        URIBuilder ub = new URIBuilder();
        ub.setPath(url);

        ArrayList<NameValuePair> pairs = covertParams2NVPS(params);
        ub.setParameters(pairs);

        HttpGet httpGet = new HttpGet(ub.build());
        for (Map.Entry<String, Object> param : headers.entrySet()) {
            httpGet.addHeader(param.getKey(), String.valueOf(param.getValue()));
        }
        return getResult(httpGet);
    }

    public static String post(String url) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        return getResult(httpPost);
    }

    public static String post(String url, Map<String, Object> params) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        ArrayList<NameValuePair> pairs = covertParams2NVPS(params);
        httpPost.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8"));
        return getResult(httpPost);
    }

    public static String post(String url, String json) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        StringEntity entity = new StringEntity(json, "UTF-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);
        return getResult(httpPost);

    }

    public static String post(String url, Map<String, Object> headers, String json) throws Exception {
        HttpPost httpPost = new HttpPost(url);

        for (Map.Entry<String, Object> param : headers.entrySet()) {
            httpPost.addHeader(param.getKey(), String.valueOf(param.getValue()));
        }
        StringEntity entity = new StringEntity(json, "UTF-8");
        entity.setContentType("application/json");
        httpPost.setEntity(entity);

        return getResult(httpPost);
    }


    public static String post(String url, Map<String, Object> headers, Map<String, Object> params) throws Exception {
        HttpPost httpPost = new HttpPost(url);

        for (Map.Entry<String, Object> param : headers.entrySet()) {
            httpPost.addHeader(param.getKey(), String.valueOf(param.getValue()));
        }

        ArrayList<NameValuePair> pairs = covertParams2NVPS(params);
        httpPost.setEntity(new UrlEncodedFormEntity(pairs, "UTF-8"));

        return getResult(httpPost);
    }

    private static ArrayList<NameValuePair> covertParams2NVPS(Map<String, Object> params) {
        ArrayList<NameValuePair> pairs = new ArrayList<NameValuePair>();
        for (Map.Entry<String, Object> param : params.entrySet()) {
            pairs.add(new BasicNameValuePair(param.getKey(), String
                    .valueOf(param.getValue())));
        }

        return pairs;
    }


    /**
     * 连接，一般给记录日志用
     * 使用 Map按key进行排序，拼接key和value
     *
     * @param map
     * @return
     */
    public static String sortMapAndKeyJointValue(Map<String, String> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Map<String, String> sortMap = new TreeMap<String, String>(map);
        Set es1 = sortMap.entrySet();//所有参与传参的参数按照accsii排序（升序）
        StringBuffer sb1 = new StringBuffer();
        Iterator it1 = es1.iterator();
        while (it1.hasNext()) {
            Map.Entry entry = (Map.Entry) it1.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue() == null ? "" : entry.getValue();
            sb1.append(k + "=" + v + "&");
        }

        return sb1.toString().substring(0, sb1.length() - 1);
    }




    /**
     * 连接，一般给记录日志用
     * 使用 不进行排序，拼接key和value
     *
     * @param map
     * @return
     */
    public static String mapAndKeyJointValue(Map<String, String> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Set es1 = map.entrySet();
        StringBuffer sb1 = new StringBuffer();
        Iterator it1 = es1.iterator();
        while (it1.hasNext()) {
            Map.Entry entry = (Map.Entry) it1.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue() == null ? "" : entry.getValue();
            sb1.append(k + "=" + v + "&");
        }

        return sb1.toString().substring(0, sb1.length() - 1);
    }



    /**
     * 拼接value
     * 连接，一般给记录日志用
     * 使用 不进行排序，只拼接value
     *
     * @param map
     * @return
     */
    public static String mapAndJointValue(Map<String, String> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Set es1 = map.entrySet();
        StringBuffer sb1 = new StringBuffer();
        Iterator it1 = es1.iterator();
        while (it1.hasNext()) {
            Map.Entry entry = (Map.Entry) it1.next();
            Object v = entry.getValue() == null ? "" : entry.getValue();
            sb1.append(v);
        }

        return sb1.toString();
    }



    /**
     * 组装url，一般给记录日志用
     *
     * @param url
     * @param params
     * @return
     */
    public static String buildGetUrl(String url, Map<String, Object> params) {
        StringBuffer uriStr = new StringBuffer(url);
        if (params != null) {
            List<NameValuePair> ps = new ArrayList<NameValuePair>();
            for (String key : params.keySet()) {
                Object o = params.get(key) == null ? "" : params.get(key);
                ps.add(new BasicNameValuePair(key, o.toString()));
            }
            uriStr.append("?");
            uriStr.append(URLEncodedUtils.format(ps, UTF_8));
        }
        String uri = uriStr.toString();
        logger.info("HttpKit.buildGetUrl请求url："+uri);
        return uri;
    }


    /**
     * 处理Http请求
     *
     * @param request
     * @return
     */
    private static String getResult(HttpRequestBase request) throws Exception {

        CloseableHttpClient httpClient = getHttpClient();
        CloseableHttpResponse response = null;

        try {

            response = httpClient.execute(request);

            // CloseableHttpClient httpClient = HttpClients.createDefault();
            response.getStatusLine().getStatusCode();
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                // long len = entity.getContentLength();// -1 表示长度未知
                String result = EntityUtils.toString(entity);
//                logger.info("请求结果："+result);
                return result;
            }
        } catch (Exception e) {
            logger.error("请求异常！", e);
            throw e;
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return EMPTY_STR;
    }


    public static void main(String[] args) {
//        String s = get("http://localhost:20050/serv/dict/getList");
//        System.out.println(1);

        Map map = new HashMap();
        map.put("time", "1602839892558");
        map.put("order_id", "25431029");
        String sign = "756A66230995FC1919A0DD9CFF070816".toLowerCase();
        map.put("sign", sign);

        try {
            String result = HttpKit.post("https://supersdk.7pa.com/order/pardon", map);
            System.out.println(1);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
